package biz.yfsoft.app.fastframework.snaker;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.snaker.engine.SnakerEngine;
import org.snaker.engine.access.Page;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.Order;
import org.snaker.engine.entity.Task;
import org.snaker.engine.model.TaskModel.TaskType;
import org.snaker.jfinal.plugin.SnakerPlugin;

import biz.yfsoft.app.fastframework.admin.AdminController;

/**
 * 工作流控制器
 *
 * @author yanhao
 */
public abstract class WorkFlowController extends AdminController {

	/**
	 * 通过插件获取流程引擎入口
	 */
	protected SnakerEngine engine = SnakerPlugin.getEngine();

	// 待执行任务
	protected String FASEWORKESQL = "SELECT * FROM view_fast_work WHERE 1=1";

	// 历史任务
	protected String HSITFASEWORKESQL = "SELECT * FROM view_hist_fast_work WHERE 1=1";

	// 流程表
	protected String PROCESSSQL = "SELECT * FROM view_wf_process WHERE 1=1";

	// 流程表ID
	public String PROCESSSQLID = "SELECT ID FROM view_wf_process WHERE 1=1";
	
	
	/**
	 * 表单页面
	 */
	public abstract void form();

	/**
	 * 主页
	 */
	public abstract void page();
	
	/**
	 * 创建实例、任务并且启动
	 * 
	 * @param processId
	 *            工作流的编号
	 * @param operator
	 *            创建者
	 * @param params
	 *            实例参数、任务参数
	 * @return
	 */
	protected Order startInstanceById(String processId, String operator,
			Map<String, Object> params) {
		return engine.startInstanceById(processId, operator, params);
	}

	/**
	 * 执行任务
	 * 
	 * @param taskId
	 *            任务编号
	 * @param operator
	 *            执行者
	 * @param params
	 *            执行参数
	 * @return
	 */
	protected List<Task> executeTask(String taskId, String operator,
			Map<String, Object> params) {
		return engine.executeTask(taskId, operator, params);
	}

	protected String processId;
	
	public void setProcessId(String processId){
		this.processId = processId;
	}
	
	/**
	 * 创建实例任务并且执行
	 * 
	 * @param processId
	 * @param params
	 * @return
	 */
	protected Order startAndExecute(String processId, Map<String, Object> params) {
		String operator = params.get("operator").toString();
		Map<String, Object> ps = new HashMap<String, Object>();
		ps.putAll(params);
		
		ps.put("actorId", operator);
		System.out.println(params);
		System.out.println(ps);
		Order order = startInstanceById(processId, operator, ps);
		List<Task> tasks = engine.query().getActiveTasks(
				new QueryFilter().setOrderId(order.getId()).setOperator(
						operator));
		List<Task> newTasks = new ArrayList<Task>();
		if (tasks != null && tasks.size() > 0) {
			Task task = tasks.get(0);
			newTasks.addAll(executeTask(task.getId(), operator, params));
		}
		return order;
	}

	// 转办
	public List<Task> transferMajor(String taskId, String operator,
			String... actors) {
		List<Task> tasks = engine.task().createNewTask(taskId,
				TaskType.Major.ordinal(), actors);
		engine.task().complete(taskId, operator);
		return tasks;
	}

	// 协办
	public List<Task> transferAidant(String taskId, String operator,
			String... actors) {
		List<Task> tasks = engine.task().createNewTask(taskId,
				TaskType.Aidant.ordinal(), actors);
		engine.task().complete(taskId, operator);
		return tasks;
	}

	/**
	 * 查询（任务、实例、工作流、参与者）关联
	 * 
	 * @param sql
	 *            数据库
	 * @param entryClass
	 *            实体类型
	 * @param page
	 *            分页
	 * @param params
	 *            参数
	 * @param orderFields
	 *            排序字段
	 * @param order
	 *            排序规则
	 * @return
	 */
	protected <T> T find(String sql, Class<T> entryClass,
			Map<String, Object> params) {
		List<T> entites = query(sql, entryClass, params);
		if (entites != null && entites.size() == 1)
			return entites.get(0);
		return null;
	}

	public <T> List<T> query(String sql, Class<T> entryClass,
			Map<String, Object> params) {
		return query(sql, entryClass, null, params, null, null);
	}

	protected <T> List<T> query(String sql, Class<T> entryClass, Page<T> page,
			Map<String, Object> params, String orderFields, String order) {
		StringBuffer sb = new StringBuffer(sql);
		Object[] o = new Object[(params != null) ? ((orderFields != null) ? (params
				.size() + 2) : params.size())
				: ((orderFields != null) ? (2) : 0)];
		int i = 0;
		if (params != null) {
			for (Iterator<String> iterator = params.keySet().iterator(); iterator
					.hasNext();) {
				String key = iterator.next();
				sb.append(" AND " + key + "=?");
				o[i++] = params.get(key);
			}
		}
		if (orderFields != null) {
			sb.append(" ORDER BY ? ?");
			o[i++] = orderFields;
			o[i] = order;
		}
		if (page == null)
			return engine.query().nativeQueryList(entryClass, sb.toString(), o);
		return engine.query().nativeQueryList(page, entryClass, sb.toString(),
				o);
	}

}
